from sklearn.decomposition import PCA#PCA算法
import Read_data
from sklearn.preprocessing import MinMaxScaler
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
import write_data
'''
PCA处理模块
输入：处理数据（list），目的维度（int）
输出：降维后数据（list），饼图
'''

class PCAprocess:

    #初始化
    def __init__(self,input_data,output_dim=3,placename='九寨沟'):
        self.placename=placename
        self.output_dim=output_dim
        self.input_data=input_data
        self.scaled_data=[]
        self.output_data=[]
        self.ratio=[]
        self.mainProcess()

    
    #main函数
    def mainProcess(self):

        #归一化
        scaler = MinMaxScaler(feature_range=(0, 1)).fit(self.input_data)
        self.scaled_data = scaler.transform(self.input_data)

        #降维，不进行归一化还原，无意义
        self.downDim()
        output=self.output_data 
        self.draw_pie(self.ratio)

        #画图数据2饼图
        pie_index=list(range(1,len(self.ratio)+1))
        index_np=np.array(pie_index).reshape((-1,1))
        ratio_np=np.array(self.ratio).reshape((-1,1))
        pie_data=np.hstack((index_np,ratio_np))
        write_data.write_data('PredictionResult/'+self.placename+'饼图PCA_主特征_所占比例_画图数据.xls',pie_data)


    #降维
    def downDim(self):
        n=self.output_dim
        data=self.scaled_data
        pca = PCA(n_components=n)

        #异常处理：数组为nan值异常。
        try:
            #用X来训练PCA模型，同时返回降维后的数据，
            self.output_data = pca.fit(data).transform(data)
        except :
            pass
        
        self.output_data=self.output_data.tolist()
        self.ratio=pca.explained_variance_ratio_
        

    #画饼图
    def draw_pie(self,quants):
        plt.figure(figsize=(16,13)) #创建画布。大小为10*10，像素为300
        labels = ['融合特征1', '融合特征2', '融合特征3']
        plt.pie(quants,radius=1,wedgeprops=dict(width=0.5,edgecolor='w'),labels=labels)
        mpl.rcParams['font.sans-serif']=['SimHei']  #使用指定的汉字字体类型（此处为黑体）
        plt.rcParams['font.size']=26 # 设置字体大小
        plt.title('主成分占比') 
        plt.savefig("PredictionResult/"+self.placename+"特征融合饼图.png")
        plt.show()

# #联调测试
# rd=Read_data.Read_data("data_siguniangshan.xlsx")
# sdata=rd.outputdata
# PCAprocess(sdata,3)

        